package com.example.airole.application.controller;

import com.example.airole.business.entity.Conversation;
import com.example.airole.business.service.ConversationService;
import com.example.airole.common.annotation.ApiVersion;
import com.example.airole.common.entity.BaseResponse;
import com.example.airole.common.entity.ResponseCode;
import com.example.airole.common.entity.Role;
import com.example.airole.common.exception.BusinessException;
import com.example.airole.llm.entity.ChatResponse;
import com.example.airole.llm.service.LLMService;
import com.example.airole.speech.entity.SpeechRecognitionResponse;
import com.example.airole.tts.entity.TTSResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 统一API控制器 - v1版本
 * 整合所有AI服务功能，提供统一的RESTful API接口
 */
@Slf4j
@RestController
@RequestMapping("/api/v1")
@ApiVersion(1)
@RequiredArgsConstructor
public class UnifiedApiController {

    private final ConversationService conversationService;
    private final LLMService llmService;

    // ==================== 对话管理 API ====================

    /**
     * 获取对话列表
     */
    @GetMapping("/conversations")
    public BaseResponse<List<Conversation>> getConversations(
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId,
            @RequestParam(value = "page", defaultValue = "0") int page,
            @RequestParam(value = "size", defaultValue = "20") int size) {
        
        try {
            List<Conversation> conversations = conversationService.getSessionConversations(sessionId);
            return BaseResponse.success("获取对话列表成功", conversations);
        } catch (Exception e) {
            log.error("获取对话列表异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "获取对话列表失败: " + e.getMessage());
        }
    }

    /**
     * 创建对话
     */
    @PostMapping("/conversations")
    public BaseResponse<Conversation> createConversation(
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId,
            @RequestParam(value = "roleId", required = false) String roleId,
            @RequestParam(value = "title", required = false) String title) {
        
        try {
            Conversation conversation = conversationService.createConversation(sessionId, roleId, title);
            return BaseResponse.success("对话创建成功", conversation);
        } catch (Exception e) {
            log.error("创建对话异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "创建对话失败: " + e.getMessage());
        }
    }

    /**
     * 获取对话详情
     */
    @GetMapping("/conversations/{conversationId}")
    public BaseResponse<Conversation> getConversation(
            @PathVariable @NotBlank(message = "对话ID不能为空") String conversationId,
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId) {
        
        try {
            Conversation conversation = conversationService.getConversation(conversationId, sessionId);
            if (conversation == null) {
                throw new BusinessException(ResponseCode.CONVERSATION_NOT_FOUND);
            }
            return BaseResponse.success("获取对话详情成功", conversation);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取对话详情异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "获取对话详情失败: " + e.getMessage());
        }
    }

    /**
     * 更新对话
     */
    @PutMapping("/conversations/{conversationId}")
    public BaseResponse<Conversation> updateConversation(
            @PathVariable @NotBlank(message = "对话ID不能为空") String conversationId,
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId,
            @RequestBody Map<String, Object> updateData) {
        
        try {
            // 更新对话标题
            if (updateData.containsKey("title")) {
                String title = (String) updateData.get("title");
                boolean updated = conversationService.updateConversationTitle(conversationId, title, sessionId);
                if (!updated) {
                    throw new BusinessException(ResponseCode.CONVERSATION_NOT_FOUND);
                }
            }
            
            Conversation conversation = conversationService.getConversation(conversationId, sessionId);
            return BaseResponse.success("对话更新成功", conversation);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新对话异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "更新对话失败: " + e.getMessage());
        }
    }

    /**
     * 删除对话
     */
    @DeleteMapping("/conversations/{conversationId}")
    public BaseResponse<Boolean> deleteConversation(
            @PathVariable @NotBlank(message = "对话ID不能为空") String conversationId,
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId) {
        
        try {
            boolean deleted = conversationService.deleteConversation(conversationId, sessionId);
            if (!deleted) {
                throw new BusinessException(ResponseCode.CONVERSATION_NOT_FOUND);
            }
            return BaseResponse.success("对话删除成功", true);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除对话异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "删除对话失败: " + e.getMessage());
        }
    }

    // ==================== AI服务 API ====================

    /**
     * 文本聊天
     */
    @PostMapping("/ai/chat/text")
    public BaseResponse<ChatResponse> textChat(
            @RequestParam @NotBlank(message = "消息内容不能为空") String text,
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId,
            @RequestParam(value = "conversationId", required = false) String conversationId,
            @RequestParam(value = "roleId", required = false, defaultValue = "assistant") String roleId) {
        
        try {
            // 获取或创建对话
            Conversation conversation = getOrCreateConversation(conversationId, sessionId, roleId);
            
            // 发送文本消息
            ChatResponse response = conversationService.sendTextMessage(
                    conversation.getConversationId(), text, sessionId, roleId);
            
            if (!response.isSuccess()) {
                throw new BusinessException(ResponseCode.LLM_ERROR.getCode(), 
                        "文本聊天失败: " + response.getErrorMessage());
            }
            
            return BaseResponse.success("文本聊天成功", response);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("文本聊天异常", e);
            throw new BusinessException(ResponseCode.LLM_ERROR.getCode(), "文本聊天失败: " + e.getMessage());
        }
    }

    /**
     * 语音聊天（完整流程）
     */
    @PostMapping("/ai/chat/audio")
    public BaseResponse<VoiceChatResponse> voiceChat(
            @RequestParam @NotNull(message = "音频文件不能为空") MultipartFile audio,
            @RequestParam @NotBlank(message = "会话ID不能为空") String sessionId,
            @RequestParam(value = "conversationId", required = false) String conversationId,
            @RequestParam(value = "roleId", required = false, defaultValue = "assistant") String roleId,
            @RequestParam(value = "language", required = false, defaultValue = "zh-CN") String language) {
        
        try {
            log.info("开始语音聊天流程，会话ID: {}, 角色ID: {}", sessionId, roleId);
            
            // 1. 语音识别
            SpeechRecognitionResponse recognitionResponse = conversationService.speechToText(audio);
            if (!recognitionResponse.isSuccess()) {
                throw new BusinessException(ResponseCode.SPEECH_RECOGNITION_ERROR.getCode(),
                        "语音识别失败: " + recognitionResponse.getErrorMessage());
            }
            
            String recognizedText = recognitionResponse.getText();
            log.info("语音识别成功: {}", recognizedText);
            
            // 2. 获取或创建对话
            Conversation conversation = getOrCreateConversation(conversationId, sessionId, roleId);
            
            // 3. LLM生成回复
            ChatResponse chatResponse = conversationService.sendTextMessage(
                    conversation.getConversationId(), recognizedText, sessionId, roleId);
            
            if (!chatResponse.isSuccess()) {
                throw new BusinessException(ResponseCode.LLM_ERROR.getCode(),
                        "LLM生成回复失败: " + chatResponse.getErrorMessage());
            }
            
            String aiResponse = chatResponse.getContent();
            log.info("LLM生成回复成功: {}", aiResponse);
            
            // 4. TTS转语音
            TTSResponse ttsResponse = conversationService.textToSpeech(aiResponse);
            if (!ttsResponse.isSuccess()) {
                throw new BusinessException(ResponseCode.TTS_ERROR.getCode(),
                        "TTS转语音失败: " + ttsResponse.getErrorMessage());
            }
            
            log.info("TTS转语音成功");
            
            // 5. 构建响应
            VoiceChatResponse response = VoiceChatResponse.builder()
                    .conversationId(conversation.getConversationId())
                    .sessionId(sessionId)
                    .roleId(roleId)
                    .userText(recognizedText)
                    .aiText(aiResponse)
                    .audioData(ttsResponse.getAudioData())
                    .audioFormat(ttsResponse.getAudioFormat())
                    .processingTime(recognitionResponse.getProcessingTime() + 
                                   chatResponse.getProcessingTime() + 
                                   ttsResponse.getProcessingTime())
                    .success(true)
                    .build();
            
            log.info("语音聊天流程完成，总耗时: {}ms", response.getProcessingTime());
            return BaseResponse.success("语音聊天成功", response);
            
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("语音聊天流程异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "语音聊天失败: " + e.getMessage());
        }
    }

    /**
     * 语音识别
     */
    @PostMapping("/ai/speech/recognize")
    public BaseResponse<SpeechRecognitionResponse> speechRecognize(
            @RequestParam @NotNull(message = "音频文件不能为空") MultipartFile audio,
            @RequestParam(value = "language", required = false) String language,
            @RequestParam(value = "mode", required = false, defaultValue = "accurate") String mode) {
        
        try {
            SpeechRecognitionResponse response = conversationService.speechToText(audio);
            
            if (!response.isSuccess()) {
                throw new BusinessException(ResponseCode.SPEECH_RECOGNITION_ERROR.getCode(),
                        "语音识别失败: " + response.getErrorMessage());
            }
            
            return BaseResponse.success("语音识别成功", response);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("语音识别异常", e);
            throw new BusinessException(ResponseCode.SPEECH_RECOGNITION_ERROR.getCode(), 
                    "语音识别失败: " + e.getMessage());
        }
    }

    /**
     * 语音合成
     */
    @PostMapping("/ai/tts/synthesize")
    public BaseResponse<TTSResponse> ttsSynthesize(
            @RequestParam @NotBlank(message = "文本内容不能为空") String text,
            @RequestParam(value = "voice", required = false) String voice,
            @RequestParam(value = "language", required = false) String language,
            @RequestParam(value = "speed", required = false, defaultValue = "1.0") Double speed) {
        
        try {
            TTSResponse response = conversationService.textToSpeech(text);
            
            if (!response.isSuccess()) {
                throw new BusinessException(ResponseCode.TTS_ERROR.getCode(),
                        "语音合成失败: " + response.getErrorMessage());
            }
            
            return BaseResponse.success("语音合成成功", response);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("语音合成异常", e);
            throw new BusinessException(ResponseCode.TTS_ERROR.getCode(), 
                    "语音合成失败: " + e.getMessage());
        }
    }

    /**
     * 获取AI服务状态
     */
    @GetMapping("/ai/status")
    public BaseResponse<AiServiceStatus> getAiServiceStatus() {
        try {
            AiServiceStatus status = AiServiceStatus.builder()
                    .speechRecognitionAvailable(true) // 简化处理
                    .llmAvailable(llmService.isServiceAvailable())
                    .ttsAvailable(true) // 简化处理
                    .build();
            
            return BaseResponse.success("AI服务状态检查完成", status);
        } catch (Exception e) {
            log.error("检查AI服务状态异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "检查AI服务状态失败: " + e.getMessage());
        }
    }

    // ==================== 角色管理 API ====================

    /**
     * 获取角色列表
     */
    @GetMapping("/roles")
    public BaseResponse<Role[]> getRoles(
            @RequestParam(value = "category", required = false) String category,
            @RequestParam(value = "isPublic", required = false) Boolean isPublic) {
        
        try {
            Role[] roles = llmService.getRoles(category, isPublic);
            return BaseResponse.success("获取角色列表成功", roles);
        } catch (Exception e) {
            log.error("获取角色列表异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "获取角色列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/roles/{roleId}")
    public BaseResponse<Role> getRole(@PathVariable @NotBlank(message = "角色ID不能为空") String roleId) {
        try {
            Role role = llmService.getRole(roleId);
            if (role == null) {
                throw new BusinessException(ResponseCode.ROLE_NOT_FOUND);
            }
            return BaseResponse.success("获取角色详情成功", role);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("获取角色详情异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "获取角色详情失败: " + e.getMessage());
        }
    }

    /**
     * 创建角色
     */
    @PostMapping("/roles")
    public BaseResponse<Role> createRole(@RequestBody @Valid Role role) {
        try {
            Role createdRole = llmService.createRole(role);
            return BaseResponse.success("角色创建成功", createdRole);
        } catch (Exception e) {
            log.error("创建角色异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "创建角色失败: " + e.getMessage());
        }
    }

    /**
     * 更新角色
     */
    @PutMapping("/roles/{roleId}")
    public BaseResponse<Role> updateRole(
            @PathVariable @NotBlank(message = "角色ID不能为空") String roleId,
            @RequestBody @Valid Role role) {
        
        try {
            role.setRoleId(roleId);
            Role updatedRole = llmService.updateRole(role);
            return BaseResponse.success("角色更新成功", updatedRole);
        } catch (Exception e) {
            log.error("更新角色异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "更新角色失败: " + e.getMessage());
        }
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/roles/{roleId}")
    public BaseResponse<Boolean> deleteRole(@PathVariable @NotBlank(message = "角色ID不能为空") String roleId) {
        try {
            boolean deleted = llmService.deleteRole(roleId);
            if (!deleted) {
                throw new BusinessException(ResponseCode.ROLE_NOT_FOUND);
            }
            return BaseResponse.success("角色删除成功", true);
        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除角色异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "删除角色失败: " + e.getMessage());
        }
    }

    // ==================== 系统管理 API ====================

    /**
     * 健康检查
     */
    @GetMapping("/system/health")
    public BaseResponse<Map<String, Object>> healthCheck() {
        Map<String, Object> health = Map.of(
                "status", "UP",
                "timestamp", System.currentTimeMillis(),
                "version", "1.0.0"
        );
        return BaseResponse.success("系统健康", health);
    }

    /**
     * 系统状态
     */
    @GetMapping("/system/status")
    public BaseResponse<SystemStatus> getSystemStatus() {
        try {
            SystemStatus status = SystemStatus.builder()
                    .aiServiceStatus(getAiServiceStatus().getData())
                    .databaseStatus("UP") // 简化处理
                    .fileSystemStatus("UP") // 简化处理
                    .build();
            
            return BaseResponse.success("系统状态检查完成", status);
        } catch (Exception e) {
            log.error("检查系统状态异常", e);
            throw new BusinessException(ResponseCode.ERROR.getCode(), "检查系统状态失败: " + e.getMessage());
        }
    }

    // ==================== 私有方法 ====================

    /**
     * 获取或创建对话
     */
    private Conversation getOrCreateConversation(String conversationId, String sessionId, String roleId) {
        if (conversationId != null && !conversationId.isEmpty()) {
            Conversation conversation = conversationService.getConversation(conversationId, sessionId);
            if (conversation != null) {
                return conversation;
            }
        }
        
        // 创建新对话
        return conversationService.createConversation(sessionId, roleId, "AI角色对话");
    }

    // ==================== 内部类 ====================

    /**
     * 语音聊天响应
     */
    @lombok.Data
    @lombok.Builder
    public static class VoiceChatResponse {
        private String conversationId;
        private String sessionId;
        private String roleId;
        private String userText;
        private String aiText;
        private String audioData;
        private String audioFormat;
        private Long processingTime;
        private boolean success;
    }

    /**
     * AI服务状态
     */
    @lombok.Data
    @lombok.Builder
    public static class AiServiceStatus {
        private boolean speechRecognitionAvailable;
        private boolean llmAvailable;
        private boolean ttsAvailable;
    }

    /**
     * 系统状态
     */
    @lombok.Data
    @lombok.Builder
    public static class SystemStatus {
        private AiServiceStatus aiServiceStatus;
        private String databaseStatus;
        private String fileSystemStatus;
    }
}
